<script setup lang="ts">
import { Environment } from '@/api/code/environment/type';
import MonacoEditor from './MonacoEditor.vue';
import Header from './Header.vue';
import { ref, Ref, watch, onMounted, onUnmounted } from 'vue';
import * as monaco from 'monaco-editor'
import { runCode } from '@/api/code';
import ExecuteTerm from './ExecuteTerm.vue';
import { CodeContent } from '@/api/code/type';
import { showNotify } from 'vant';
import eventBus from '@/utils/eventBus'; // 假设有一个事件总线工具

const codeId = defineModel("codeId") as Ref<string>;
const environment = defineModel() as Ref<Environment>;
const codeContent = defineModel("codeContent") as Ref<CodeContent>;
const options = ref({} as monaco.editor.IStandaloneEditorConstructionOptions);
const show = ref(false);
const showContent = ref('');
const terminalHeight = ref(300); // 设置默认高度
const isRunning = ref(false);
const isResizing = ref(false);
const startResizeY = ref(0);
const initialTerminalHeight = ref(0);

// 监听环境变化设置语言
watch(environment, () => {
    if (environment.value.type != undefined && environment.value.type != null) {
        options.value.language = environment.value.type;
    }
});

// 运行代码
const run = () => {
    showContent.value = '';
    isRunning.value = true;
    
    try {
        runCode(codeId.value, codeContent.value.content)
            .then(() => {
                show.value = true;
                showNotify({ 
                    type: 'primary', 
                    message: '代码正在执行中...',
                    position: 'top'
                });
            })
            .catch(error => {
                console.error('运行代码失败:', error);
                showNotify({ 
                    type: 'danger', 
                    message: '运行代码失败，请重试',
                    position: 'top'
                });
                isRunning.value = false;
            });
    } catch (error) {
        console.error('运行代码请求错误:', error);
        showNotify({ 
            type: 'danger', 
            message: '运行代码失败，请重试',
            position: 'top'
        });
        isRunning.value = false;
    }
}

// 终端调整大小功能
const startResize = (event: MouseEvent) => {
    isResizing.value = true;
    startResizeY.value = event.clientY;
    initialTerminalHeight.value = terminalHeight.value;
    
    // 添加全局事件监听器
    document.addEventListener('mousemove', handleResize);
    document.addEventListener('mouseup', stopResize);
}

const handleResize = (event: MouseEvent) => {
    if (!isResizing.value) return;
    
    const deltaY = startResizeY.value - event.clientY;
    const newHeight = initialTerminalHeight.value + deltaY;
    
    // 限制最小和最大高度
    if (newHeight >= 100 && newHeight <= window.innerHeight * 0.8) {
        terminalHeight.value = newHeight;
    }
}

const stopResize = () => {
    isResizing.value = false;
    document.removeEventListener('mousemove', handleResize);
    document.removeEventListener('mouseup', stopResize);
}

// 替代 Tauri 的监听方式
onMounted(() => {
    // 添加执行结果监听器
    eventBus.on('execute-message', handleExecuteMessage);
    
    // WebSocket 替代方案 (如果使用这种方式)
    setupWebSocketListener();
});

onUnmounted(() => {
    // 移除监听器
    eventBus.off('execute-message', handleExecuteMessage);
    
    // WebSocket 清理
    cleanupWebSocketListener();
});

// WebSocket 相关代码
let socket: WebSocket | null = null;

const setupWebSocketListener = () => {
    // 根据实际情况使用正确的 WebSocket URL
    const wsUrl = `ws://${window.location.host}/api/code/execute/${codeId.value}`;
    
    try {
        socket = new WebSocket(wsUrl);
        
        socket.onopen = () => {
            console.log('WebSocket 连接已建立');
        };
        
        socket.onmessage = (event) => {
            handleExecuteMessage(event.data);
        };
        
        socket.onerror = (error) => {
            console.error('WebSocket 错误:', error);
        };
        
        socket.onclose = () => {
            console.log('WebSocket 连接已关闭');
        };
    } catch (error) {
        console.error('创建 WebSocket 连接失败:', error);
    }
};

const cleanupWebSocketListener = () => {
    if (socket && socket.readyState === WebSocket.OPEN) {
        socket.close();
    }
};

// 处理执行消息
const handleExecuteMessage = (payload: string) => {
    try {
        if (typeof payload !== 'string') {
            payload = JSON.stringify(payload);
        }
        
        const a = payload.replace(/[\r\n]/g, "");
        const b = codeContent.value.content.replace(/[\r\n]/g, "");
        
        if (a.includes(b) && (a.length - b.length) <= 5) {
            return;
        }
        
        showContent.value = showContent.value + payload;
        
        // 检测执行完成的标志
        if (payload.includes('执行完成') || payload.includes('Execution completed')) {
            isRunning.value = false;
            showNotify({ 
                type: 'success', 
                message: '代码执行完成',
                position: 'top'
            });
        }
    } catch (error) {
        console.error('处理执行消息失败:', error);
    }
};

// 另一种替代 Tauri 的方式: 轮询 API
// const startPolling = () => {
//     const interval = setInterval(async () => {
//         if (!isRunning.value) {
//             clearInterval(interval);
//             return;
//         }
//         
//         try {
//             const response = await fetch(`/api/code/execution-output/${codeId.value}`);
//             const data = await response.text();
//             
//             if (data && data !== showContent.value) {
//                 handleExecuteMessage(data);
//             }
//         } catch (error) {
//             console.error('轮询执行结果失败:', error);
//         }
//     }, 1000); // 每秒轮询一次
// };

</script>

<template>
    <div class="code-editor-container">
        <!-- 工具栏 -->
        <Header 
            class="editor-header" 
            @run="run" 
            v-model:codeId="codeId" 
            v-model:name="environment.name"
            v-model:codeContent="codeContent" 
            v-model:termContent="showContent" 
        />
        
        <!-- 编辑器和终端区域 -->
        <div class="editor-workspace" :class="{ 'with-terminal': show }">
            <!-- 代码编辑器 -->
            <MonacoEditor 
                v-model:content="codeContent.content" 
                class="monaco-editor" 
            />
            
            <!-- 终端输出区域 -->
            <div v-if="show" class="terminal-container" :style="{ height: `${terminalHeight}px` }">
                <!-- 调整大小的拖动条 -->
                <div class="terminal-resize-handle" @mousedown="startResize">
                    <div class="handle-line"></div>
                </div>
                
                <!-- 终端标题栏 -->
                <div class="terminal-header">
                    <span class="terminal-title">
                        <van-icon name="terminal-o" />
                        执行结果
                        <span v-if="isRunning" class="running-indicator">
                            <van-loading size="14" type="spinner" />
                            运行中...
                        </span>
                    </span>
                    <div class="terminal-actions">
                        <van-button 
                            size="small" 
                            icon="close" 
                            round 
                            @click="show = false"
                            class="close-btn"
                            plain
                        />
                    </div>
                </div>
                
                <!-- 终端内容 -->
                <div class="terminal-content">
                    <ExecuteTerm v-model="showContent" />
                </div>
            </div>
        </div>
    </div>
</template>

<style lang="scss" scoped>
.code-editor-container {
    height: 100%;
    width: 100%;
    display: flex;
    flex-direction: column;
    background-color: #1e1e1e;
    
    .editor-header {
        flex-shrink: 0;
        height: 48px;
        border-bottom: 1px solid rgba(255, 255, 255, 0.1);
        background-color: #252526;
    }
    
    .editor-workspace {
        flex: 1;
        display: flex;
        flex-direction: column;
        position: relative;
        height: calc(100% - 48px);
        
        &.with-terminal {
            .monaco-editor {
                height: calc(100% - v-bind('terminalHeight + "px"'));
            }
        }
        
        .monaco-editor {
            flex: 1;
            min-height: 100px;
            transition: height 0.2s ease;
        }
        
        .terminal-container {
            position: relative;
            width: 100%;
            background-color: #1a1a1a;
            border-top: 1px solid rgba(255, 255, 255, 0.1);
            transition: height 0.2s ease;
            
            .terminal-resize-handle {
                position: absolute;
                top: -5px;
                left: 0;
                right: 0;
                height: 10px;
                cursor: ns-resize;
                z-index: 10;
                display: flex;
                justify-content: center;
                align-items: center;
                
                .handle-line {
                    width: 50px;
                    height: 3px;
                    background-color: rgba(255, 255, 255, 0.2);
                    border-radius: 1.5px;
                    transition: background-color 0.2s ease;
                    
                    &:hover {
                        background-color: rgba(255, 255, 255, 0.5);
                    }
                }
            }
            
            .terminal-header {
                height: 32px;
                padding: 0 12px;
                display: flex;
                align-items: center;
                justify-content: space-between;
                background-color: #252526;
                border-bottom: 1px solid rgba(255, 255, 255, 0.1);
                
                .terminal-title {
                    color: #e0e0e0;
                    font-size: 12px;
                    display: flex;
                    align-items: center;
                    gap: 6px;
                    
                    .running-indicator {
                        display: flex;
                        align-items: center;
                        gap: 4px;
                        margin-left: 12px;
                        color: #5ccfe6;
                    }
                }
                
                .terminal-actions {
                    .close-btn {
                        height: 24px;
                        opacity: 0.7;
                        
                        &:hover {
                            opacity: 1;
                        }
                    }
                }
            }
            
            .terminal-content {
                height: calc(100% - 32px);
            }
        }
    }
}
</style>